#pragma once

#include "simulation_clock.h"
#include "physics_simulator.h"
#include "kernel/interfaces/ILogger.h"
#include <QObject>
#include <QTimer>
#include <memory>
#include <QSet>

namespace application {

class MapApplicationService;

namespace vehicle {
    class VehicleService;
}

namespace simulation {

/**
 * @brief 仿真引擎 - 协调时钟、物理模拟、车辆服务
 * @details 作为仿真系统的核心调度器
 */
class SimulationEngine : public QObject {
    Q_OBJECT

public:
    explicit SimulationEngine(
        std::shared_ptr<MapApplicationService> mapService,
        std::shared_ptr<kernel::ILogger> logger,
        QObject* parent = nullptr
    );
    ~SimulationEngine() = default;

    /**
     * @brief 初始化引擎
     */
    void init();

    /**
     * @brief 播放仿真
     */
    void play();

    /**
     * @brief 暂停仿真
     */
    void pause();

    /**
     * @brief 恢复仿真（从暂停状态）
     */
    void resume();

    /**
     * @brief 停止仿真
     */
    void stop();

    /**
     * @brief 单步推进
     * @param deltaTime 推进时间量（秒）
     */
    void step(double deltaTime);

    /**
     * @brief 设置时间缩放
     */
    void setTimeScale(double scale);

    /**
     * @brief 获取时间缩放
     */
    double getTimeScale() const;

    /**
     * @brief 获取仿真时间
     */
    double getSimulationTime() const;

    /**
     * @brief 检查是否正在运行
     */
    bool isPlaying() const { return m_isPlaying; }

    /**
     * @brief 检查是否暂停
     */
    bool isPaused() const;

    /**
     * @brief 获取物理模拟器
     */
    PhysicsSimulator* physicsSimulator() { return m_physicsSimulator.get(); }

    /**
     * @brief 获取仿真时钟
     */
    SimulationClock* clock() { return m_clock.get(); }

    /**
     * @brief 注册车辆到引擎（用于自动更新）
     */
    void registerVehicle(int agvNumber);

    /**
     * @brief 注销车辆
     */
    void unregisterVehicle(int agvNumber);

signals:
    void simulationStarted();
    void simulationPaused();
    void simulationResumed();
    void simulationStopped();
    void simulationTimeChanged(double time);

private slots:
    void onTimerTick();

private:
    std::shared_ptr<kernel::ILogger> m_logger;
    std::unique_ptr<SimulationClock> m_clock;
    std::unique_ptr<PhysicsSimulator> m_physicsSimulator;

    QTimer* m_timer;
    bool m_isPlaying;
    qint64 m_lastTickTime;  // 上次tick的时间戳（毫秒）
    QSet<int> m_registeredVehicles;  // 注册的车辆列表

    static constexpr int TIMER_INTERVAL_MS = 50;  // 20 FPS
};

} // namespace simulation
} // namespace application
